package com.artnology.independence.views.jung;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;

import javax.swing.JComponent;

import com.artnology.independence.model.DVNode;
import com.artnology.independence.model.relationships.DVReference;

import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.visualization.Layer;
import edu.uci.ics.jung.visualization.RenderContext;
import edu.uci.ics.jung.visualization.picking.PickedState;
import edu.uci.ics.jung.visualization.renderers.Renderer;
import edu.uci.ics.jung.visualization.transform.shape.GraphicsDecorator;

public class PackageColorVertexRenderer<V, E> implements Renderer.Vertex<V, E> {
	Color backgroundColor;
	
	Color pickedBackgroundColor;
	
	PickedState<V> pickedState;
	boolean cyclic;

	public PackageColorVertexRenderer(Color backgroundColor,boolean cyclic) {
		this.backgroundColor = backgroundColor;
		this.cyclic = cyclic;
	}

	public PackageColorVertexRenderer(Color backgroundColor,
			Color pickedbackgroundColor, 
			PickedState<V> pickedState, boolean cyclic) {
		this.backgroundColor = backgroundColor;
		this.pickedBackgroundColor = pickedbackgroundColor;
		
		this.pickedState = pickedState;
		this.cyclic = cyclic;
	}

	public void paintVertex(RenderContext<V, E> rc, Layout<V, E> layout, V v) {
		Graph<DVNode, DVReference> graph = (Graph<DVNode, DVReference>) layout.getGraph();

		boolean vertexHit = true;

		Shape shape = (Shape) rc.getVertexShapeTransformer().transform(v);

		Point2D p = (Point2D) layout.transform(v);
		p = rc.getMultiLayerTransformer().transform(Layer.LAYOUT, p);

		float x = (float) p.getX();
		float y = (float) p.getY();

		AffineTransform xform = AffineTransform.getTranslateInstance(x, y);

		shape = xform.createTransformedShape(shape);

		vertexHit = vertexHit(rc, shape);

		if (vertexHit)
			paintShapeForVertex(rc, v, shape);

	}

	protected boolean vertexHit(RenderContext<V, E> rc, Shape s) {
		JComponent vv = rc.getScreenDevice();
		Rectangle deviceRectangle = null;
		if (vv != null) {
			Dimension d = vv.getSize();
			deviceRectangle = new Rectangle(0, 0, d.width, d.height);
		}

		return rc.getMultiLayerTransformer().getTransformer(Layer.VIEW)
				.transform(s).intersects(deviceRectangle);
	}

	protected void paintShapeForVertex(RenderContext<V, E> rc, V v, Shape shape) {
		GraphicsDecorator g = rc.getGraphicsContext();
		Paint oldPaint = g.getPaint();
		Rectangle r = shape.getBounds();
		float y2 = (float) r.getMaxY();
		if (this.cyclic) {
			y2 = (float) (r.getMinY() + r.getHeight() / 2.0D);
		}

		Paint fillPaint = null;
		DVNode node = (DVNode) v;
		
		
		if ((this.pickedState != null) && (this.pickedState.isPicked(v))) {
			fillPaint = new GradientPaint((float) r.getMinX(),
					(float) r.getMinY(), node.getNodeFillColor(),
					(float) r.getMinX(), y2,this.pickedBackgroundColor , this.cyclic);
		} else {
			fillPaint = new GradientPaint((float) r.getMinX(),
					(float) r.getMinY(),node.getNodeFillColor() , (float) r.getMinX(),
					y2, this.backgroundColor, this.cyclic);
		}

		if (fillPaint != null) {
			g.setPaint(fillPaint);
			g.fill(shape);
			g.setPaint(oldPaint);
		}
		Paint drawPaint = (Paint) rc.getVertexDrawPaintTransformer().transform(
				v);
		if (drawPaint != null) {
			g.setPaint(drawPaint);
		}
		Stroke oldStroke = g.getStroke();
		Stroke stroke = (Stroke) rc.getVertexStrokeTransformer().transform(v);
		if (stroke != null) {
			g.setStroke(stroke);
		}
		g.draw(shape);
		g.setPaint(oldPaint);
		g.setStroke(oldStroke);
	}
}
